﻿using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;

namespace Microsoft.WowAddonStudio.FrameXml.Formats.Tga
{
    public class TargaImage
    {
        /// <summary>
        /// Loads the file from the specified fileName.
        /// </summary>
        /// <param name="fileName">Name of the file.</param>
        /// <returns>Image or null</returns>
        public static Image FromFile(string fileName)
        {
            if (!File.Exists(fileName))
                return null;

            using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                return FromStream(stream);
            }
        }

        /// <summary>
        /// Loads a Targa image from a stream.
        /// </summary>
        /// <param name="stream">The stream to load the Targa image from.</param>
        /// <returns>An instance of the <see cref="Image"/> class.</returns>
        public static Image FromStream(Stream stream)
        {
            if (stream == null)
                throw new ArgumentNullException("stream");

            var header = new byte[18];

            stream.Read(header, 0, header.Length);

            int width = header[12] + (header[13] << 8);
            int height = header[14] + (header[15] << 8);
            byte colorDepth = header[16];
            byte imageDescriptor = header[17];

            if (colorDepth != 32)
            {
                Trace.WriteLine("Color depth should be 32");
                return null;
            }

            // handling color map
            if (header[1] != 0)
            {
                Trace.WriteLine("Color maps are not supported");
                return null;
            }

            // image type
            if (header[2] > 3)
            {
                Trace.WriteLine("Encoded or compressed images are not supported");
                return null;
            }

            // bypass image ID
            var imageID = new byte[header[0]];
            stream.Read(imageID, 0, imageID.Length);

            bool origoTop = ((imageDescriptor & 0x20) != 0);
            bool origoLeft = ((imageDescriptor & 0x10) == 0);

            // we don't support color maps so there is nothing to bypass

            var bitmap = new Bitmap(width, height);
            var argb = new byte[4];

            for (int y = 0; y < height; y++)
            {
                for (int x = 0; x < width; x++)
                {
                    stream.Read(argb, 0, argb.Length);

                    var color = Color.FromArgb(argb[3], argb[2], argb[1], argb[0]);

                    bitmap.SetPixel(origoLeft ? x : width - 1 - x,
                                    origoTop ? y : height - 1 - y,
                                    color);
                }
            }

            return bitmap;
        }
    }
}